package state

import (
	"osiris/core/routine"
	"osiris/dto"
	"osiris/errors"
	"osiris/logger"
	"osiris/ocrypto/ecdsa"
)

// RegisterTxHandler 账户注册交易
type RegisterTxHandler struct {
	TxData dto.TxData
}

func (txHandler RegisterTxHandler) Verify(tries ...interface{}) bool {
	trie := tries[0]
	tempAccountTrie, ok := trie.(*AccountStateTrie)
	if !ok {
		logger.Warn(map[string]interface{}{"[state] [Verify Register TX]": "unknown trie!"})
		return false
	}
	
	addrBytes := ecdsa.StrToAccountBytes(txHandler.TxData.ToAddr)
	exist := tempAccountTrie.HasLeaf(addrBytes)
	if exist {
		logger.Warn(map[string]interface{}{"[state] [RegisterTxHandler Verify]": "account already exist"})
		return false
	}

	return true
}

func (txHandler RegisterTxHandler) Commit(tries ...interface{}) bool {
	trie := tries[0]
	tempAccountTrie, ok := trie.(*AccountStateTrie)
	if !ok {
		err := &errors.UnknownStateTrieError{}
		logger.Error(map[string]interface{}{"[state] [Commit Register TX]": err})
		return false
	}

	accountAddrBytes := ecdsa.StrToAccountBytes(txHandler.TxData.ToAddr)
	exist := tempAccountTrie.HasLeaf(accountAddrBytes)
	if exist {
		logger.Error(map[string]interface{}{"[state] [Commit Register TX]": "account already exist"})
		return false
	}

	leaf := dto.StateLeaf{
		Asset:     0,
		CoinSince: txHandler.TxData.CoinSince,
		Nonce:     txHandler.TxData.Nonce + 1,
		MaxNonce:  txHandler.TxData.MaxNonce,
	}

	batch := routine.AtomicRoutineBatch{}
	return batch.Add(&AccountCommitRoutine{
		Kvs: []StateKeyValue{{
			Key: accountAddrBytes,
			Leaf: leaf,
		}},
		Trie: tempAccountTrie,
	}).Execute()
}

// Undo 账户注册类型的交易不需要Undo，迟早会被打包进区块，如果还没被共识也不会对其它账户的交易造成影响
//
//	@receiver txHandler
//	@return error
func (txHandler RegisterTxHandler) Undo(tries ...interface{}) bool {
	return true
}
